package com.wanho.qz103.hrsaas.commons.proxy;

import com.wanho.qz103.hrsaas.commons.exception.DataAccessException;
import com.wanho.qz103.hrsaas.commons.tx.TxManager;
import com.wanho.qz103.hrsaas.commons.tx.impl.TxManagerImpl;
import com.wanho.qz103.hrsaas.commons.util.JDBCUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;

/**
 * 对 业务层方法进行增强 ：运行期 动态添加代码
 */
public class TxProxy {
    /**使用事务工具类 */
    private static TxManager txManager = new TxManagerImpl() ;

    /**
     * 创建目标类  代理类  jdk： 面向接口编程
     * @param targetObj  new 目标对象  厂家 ： 源对象  方法 没有被增强
     * @param <T>
     * @return        被代理对象：  代理商 ： 被增强的对象  方法 被增强   兄弟关系 实现相同 service接口
     */
    public static  <T> T getProxy(final Object targetObj){
        // jvm java虚拟机 类加载器
        ClassLoader loader = targetObj.getClass().getClassLoader() ;
        //接口数组
        Class<?>[] interfaces = targetObj.getClass().getInterfaces() ;
        //回调函数        可推导 即可省略  proxy 代理  method 方法对象  args 参数列表
        InvocationHandler h = (proxy, method, args) -> {
            try {
                // 开启事务
                txManager.beginTx();
                // 调用 源对象 的目标方法
                Object returnObj = method.invoke(targetObj,args);
                // 事务提交
                txManager.commitTx();
                // 返回 源对象 方法执行结果
                return returnObj ;
            }  catch (InvocationTargetException e) {
                e.printStackTrace();
                // 事务回滚
                txManager.rollbakTx();
                throw e.getTargetException() ;
            } finally {
                // 释放资源
                JDBCUtil.closeConnection(JDBCUtil.getConnection());
            }
        };
        //创建 代理实例
        return (T) Proxy.newProxyInstance(loader,interfaces,h);
    }
}
